﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BSU.CSCE.Utilities;

namespace BSU.CSCE.Data.Filters
{
    public static class CommonFilter
    {
        public static IQueryable<T> Sort<T>(this IQueryable<T> source, string sortPath, bool ascending)
        {
            if (String.IsNullOrEmpty(sortPath))
            {
                throw new ArgumentNullException("sortPath", "sortPath can not be null or empty.");
            }

            Type propertyType = Reflector.GetPropertyType<T>(sortPath);

            if (propertyType == typeof(char?))
            {
                var sortLambda = Reflector.GetPropertyLambda<T, char?>(sortPath);
                return ascending ? source.OrderBy(sortLambda) : source.OrderByDescending(sortLambda);
            }
            if (propertyType == typeof(bool?))
            {
                var sortLambda = Reflector.GetPropertyLambda<T, bool?>(sortPath);
                return ascending ? source.OrderBy(sortLambda) : source.OrderByDescending(sortLambda);
            }
            if (propertyType == typeof(Int32))
            {
                var sortLambda = Reflector.GetPropertyLambda<T, int>(sortPath);
                return ascending ? source.OrderBy(sortLambda) : source.OrderByDescending(sortLambda);
            }
            if (propertyType == typeof(Decimal))
            {
                var sortLambda = Reflector.GetPropertyLambda<T, decimal>(sortPath);
                return ascending ? source.OrderBy(sortLambda) : source.OrderByDescending(sortLambda);
            }
            if (propertyType == typeof(DateTime))
            {
                var sortLambda = Reflector.GetPropertyLambda<T, DateTime>(sortPath);
                return ascending ? source.OrderBy(sortLambda) : source.OrderByDescending(sortLambda);
            }
            if (propertyType == typeof(DateTime?))
            {
                var sortLambda = Reflector.GetPropertyLambda<T, DateTime?>(sortPath);
                return ascending ? source.OrderBy(sortLambda) : source.OrderByDescending(sortLambda);
            }
            else
            {
                var sortLambda = Reflector.GetPropertyLambda<T, object>(sortPath);
                return ascending ? source.OrderBy(sortLambda) : source.OrderByDescending(sortLambda);
            }
        }

        public static IQueryable<T> Page<T>(this IQueryable<T> source, int startIndex, int count, out int totalCount)
        {
            if (startIndex < 0)
            {
                throw new ArgumentOutOfRangeException("startIndex", "startIndex must be non negative.");
            }
            if (count < 1)
            {
                throw new ArgumentOutOfRangeException("count", "count must equal or greater than 1.");
            }
            totalCount = source.Count();
            return source.Skip(startIndex).Take(count);
        }
    }
}
